import { createRoot } from "react-dom/client";
import { createPortal } from "react-dom";
import React from "react";
import styled from "@emotion/styled";
import { motion, AnimatePresence } from "framer-motion";
import { FiX } from "react-icons/fi";
import {
  zIndex,
  duration,
  easing,
  motionEasing,
  radius,
  spacing,
} from "../utils/design-tokens";

// 模态框尺寸类型
export type ModalSize = "small" | "medium" | "large" | "full";

// 弹窗背景遮罩
const ModalOverlay = styled(motion.div)`
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: ${zIndex.modalBackdrop};
  display: flex;
  align-items: center;
  justify-content: center;
  padding: ${spacing["4"]};
  overflow-y: auto;
  overscroll-behavior: contain;

  /* 性能优化 */
  will-change: opacity;
  transform: translateZ(0);
  -webkit-transform: translateZ(0);

  /* 阻止触摸滚动穿透 */
  touch-action: none;
  -webkit-overflow-scrolling: touch;

  @media (max-width: 768px) {
    padding: ${spacing["2"]};
  }
`;

// 弹窗容器
const ModalContainer = styled(motion.div)<{
  $size: ModalSize;
  $centerContent?: boolean;
  $customWidth?: string | number;
}>`
  background: var(--bg-primary);
  border-radius: ${radius.xl};
  position: relative;
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
    0 10px 10px -5px rgba(0, 0, 0, 0.04);
  margin: auto;
  max-height: calc(100vh - ${spacing["8"]});
  overflow: hidden;
  display: flex;
  flex-direction: column;
  z-index: ${zIndex.modal};

  /* 允许内部滚动 */
  touch-action: auto;

  [data-theme="dark"] & {
    background: var(--bg-secondary);
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3),
      0 10px 10px -5px rgba(0, 0, 0, 0.2);
  }

  ${({ $size, $customWidth }) => {
    if ($customWidth) {
      const width =
        typeof $customWidth === "number" ? `${$customWidth}px` : $customWidth;
      return `width: ${width};`;
    }

    switch ($size) {
      case "small":
        return `
          width: 90%;
          max-width: 320px;
        `;
      case "large":
        return `
          width: 95%;
          max-width: 800px;
        `;
      case "full":
        return `
          width: 95%;
          max-width: 1200px;
          height: 90vh;
        `;
      default: // medium
        return `
          width: 90%;
          max-width: 500px;
        `;
    }
  }}

  ${({ $centerContent }) =>
    $centerContent &&
    `
    align-items: center;
    justify-content: center;
    text-align: center;
  `}

  @media (max-width: 768px) {
    max-height: calc(100vh - ${spacing["4"]});
  }
`;

// 弹窗头部
const ModalHeader = styled.div`
  position: relative;
  padding: ${spacing["6"]} ${spacing["8"]} ${spacing["4"]};
  border-bottom: 1px solid var(--border-color);
  flex-shrink: 0;

  @media (max-width: 768px) {
    padding: ${spacing["5"]} ${spacing["6"]} ${spacing["3"]};
  }
`;

// 弹窗标题
const ModalTitle = styled.h2`
  margin: 0;
  padding-right: ${spacing["12"]};
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.5;

  @media (max-width: 768px) {
    font-size: 1.125rem;
    padding-right: ${spacing["10"]};
  }
`;

// 弹窗内容
const ModalBody = styled.div`
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: ${spacing["6"]} ${spacing["8"]};
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-track {
    background: var(--bg-secondary);
    border-radius: ${radius.sm};
  }

  &::-webkit-scrollbar-thumb {
    background: var(--text-tertiary);
    border-radius: ${radius.sm};
  }

  &::-webkit-scrollbar-thumb:hover {
    background: var(--text-secondary);
  }

  @media (max-width: 768px) {
    padding: ${spacing["5"]} ${spacing["6"]};
  }
`;

// 弹窗底部
const ModalFooter = styled.div`
  padding: ${spacing["4"]} ${spacing["8"]} ${spacing["6"]};
  border-top: 1px solid var(--border-color);
  flex-shrink: 0;
  display: flex;
  gap: ${spacing["3"]};
  justify-content: flex-end;

  @media (max-width: 768px) {
    padding: ${spacing["3"]} ${spacing["6"]} ${spacing["5"]};
    gap: ${spacing["2"]};
  }
`;

// 关闭按钮
const CloseButton = styled.button`
  position: absolute;
  top: ${spacing["5"]};
  right: ${spacing["6"]};
  background: none;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  padding: ${spacing["2"]};
  border-radius: ${radius.full};
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all ${duration.fast}ms ${easing.ease};
  z-index: 10;
  width: 2rem;
  height: 2rem;

  &:hover {
    background: var(--bg-secondary);
    color: var(--text-primary);
    transform: scale(1.1);
  }

  &:active {
    transform: scale(0.95);
  }

  @media (max-width: 768px) {
    top: ${spacing["4"]};
    right: ${spacing["5"]};
  }
`;

// 按钮样式
const Button = styled.button<{ $variant?: "primary" | "secondary" | "danger" }>`
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.6rem 1.25rem;
  font-weight: 500;
  font-size: 0.95rem;
  border-radius: ${radius.md};
  transition: all ${duration.fast}ms ${easing.ease};
  cursor: pointer;
  outline: none;
  font-family: inherit;
  min-height: 2.5rem;

  ${({ $variant = "secondary" }) => {
    switch ($variant) {
      case "primary":
        return `
          background-color: var(--accent-color);
          color: white;
          border: 2px solid var(--accent-color);
          
          &:hover:not(:disabled) {
            background-color: var(--accent-color-hover);
            border-color: var(--accent-color-hover);
            transform: translateY(-1px);
          }
        `;
      case "danger":
        return `
          background-color: var(--error-color);
          color: white;
          border: 2px solid var(--error-color);
          
          &:hover:not(:disabled) {
            background-color: #d32f2f;
            border-color: #d32f2f;
            transform: translateY(-1px);
          }
        `;
      default:
        return `
          background-color: var(--bg-secondary);
          color: var(--text-primary);
          border: 2px solid var(--border-color);
          
          &:hover:not(:disabled) {
            background-color: var(--bg-tertiary);
            border-color: var(--accent-color-alpha);
            transform: translateY(-1px);
          }
        `;
    }
  }}

  &:focus-visible {
    outline: 2px solid var(--accent-color);
    outline-offset: 2px;
  }

  @media (max-width: 768px) {
    padding: 0.5rem 1rem;
    font-size: 0.875rem;
  }
`;

// Modal 选项接口
export interface ModalOptions {
  title?: string;
  size?: ModalSize;
  width?: number | string;
  closeOnOverlayClick?: boolean;
  closeOnEsc?: boolean;
  showCloseButton?: boolean;
  centerContent?: boolean;
  footer?: React.ReactNode;
  className?: string;
}

// Modal 组件
interface ModalComponentProps extends ModalOptions {
  isOpen: boolean;
  onClose: () => void;
  children: React.ReactNode;
  usePortal?: boolean;
}

const ModalComponent: React.FC<ModalComponentProps> = ({
  isOpen,
  onClose,
  children,
  title,
  size = "medium",
  width,
  closeOnOverlayClick = true,
  closeOnEsc = true,
  showCloseButton = true,
  centerContent = false,
  footer,
  className,
  usePortal = true,
}) => {
  const modalRef = React.useRef<HTMLDivElement>(null);

  // 处理键盘事件
  React.useEffect(() => {
    if (!isOpen) return;

    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === "Escape" && closeOnEsc) {
        onClose();
      }
    };

    document.addEventListener("keydown", handleKeyDown);
    return () => document.removeEventListener("keydown", handleKeyDown);
  }, [isOpen, closeOnEsc, onClose]);

  // 处理焦点管理
  React.useEffect(() => {
    if (!isOpen || !modalRef.current) return;

    const focusTimeout = setTimeout(() => {
      if (modalRef.current) {
        const focusableElements =
          modalRef.current.querySelectorAll<HTMLElement>(
            'button:not(:disabled), [href], input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [tabindex]:not([tabindex="-1"])'
          );

        if (focusableElements.length > 0) {
          // 优先聚焦第一个输入框
          const firstInput = Array.from(focusableElements).find(
            (el) => el.tagName === "INPUT" || el.tagName === "TEXTAREA"
          );

          if (firstInput) {
            firstInput.focus();
          } else {
            focusableElements[0].focus();
          }
        }
      }
    }, 150);

    return () => clearTimeout(focusTimeout);
  }, [isOpen]);

  // 处理点击遮罩层关闭
  const handleOverlayClick = (event: React.MouseEvent) => {
    if (closeOnOverlayClick && event.target === event.currentTarget) {
      onClose();
    }
  };

  // 阻止Modal容器的点击事件冒泡和滚动穿透
  const handleModalClick = (event: React.MouseEvent) => {
    event.stopPropagation();
  };

  // 阻止触摸滚动穿透（移动端）
  const handleTouchMove = (event: React.TouchEvent) => {
    const target = event.target as HTMLElement;
    const modalBody = modalRef.current?.querySelector(
      "[data-modal-body]"
    ) as HTMLElement;

    // 只允许 Modal 内容区域滚动
    if (modalBody && modalBody.contains(target)) {
      // 检查是否到达边界
      const isAtTop = modalBody.scrollTop === 0;
      const isAtBottom =
        modalBody.scrollHeight - modalBody.scrollTop === modalBody.clientHeight;

      if (
        (isAtTop && event.touches[0].clientY > event.touches[0].clientY) ||
        (isAtBottom && event.touches[0].clientY < event.touches[0].clientY)
      ) {
        event.preventDefault();
      }
    } else {
      // 非内容区域完全阻止滚动
      event.preventDefault();
    }
  };

  const modalContent = (
    <AnimatePresence mode="wait">
      {isOpen && (
        <ModalOverlay
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          transition={{
            duration: duration.fast / 1000,
            ease: motionEasing.ease,
          }}
          onClick={handleOverlayClick}
          onTouchMove={handleTouchMove}
        >
          <ModalContainer
            ref={modalRef}
            className={className}
            $size={size}
            $centerContent={centerContent}
            $customWidth={width}
            initial={{ scale: 0.95, opacity: 0, y: 20 }}
            animate={{ scale: 1, opacity: 1, y: 0 }}
            exit={{ scale: 0.95, opacity: 0, y: 20 }}
            transition={{
              duration: duration.normal / 1000,
              ease: motionEasing.spring,
            }}
            onClick={handleModalClick}
            tabIndex={-1}
            role="dialog"
            aria-modal="true"
            aria-labelledby={title ? "modal-title" : undefined}
          >
            {showCloseButton && (
              <CloseButton onClick={onClose} aria-label="关闭模态框">
                <FiX size={20} />
              </CloseButton>
            )}

            {title && (
              <ModalHeader>
                <ModalTitle id="modal-title">{title}</ModalTitle>
              </ModalHeader>
            )}

            <ModalBody data-modal-body>{children}</ModalBody>

            {footer && <ModalFooter>{footer}</ModalFooter>}
          </ModalContainer>
        </ModalOverlay>
      )}
    </AnimatePresence>
  );

  return usePortal ? createPortal(modalContent, document.body) : modalContent;
};

// Modal 函数式API
export interface ModalInfoOptions {
  title?: string;
  message?: React.ReactNode;
  content?: React.ReactNode;
  width?: number | string;
  size?: ModalSize;
  closeOnOverlayClick?: boolean;
  closeOnEsc?: boolean;
  showCloseButton?: boolean;
  centerContent?: boolean;
  className?: string;
}

export interface ModalAPI {
  show: (content: React.ReactNode, options?: ModalOptions) => Promise<void>;
  confirm: (options: {
    title?: string;
    message: React.ReactNode;
    confirmText?: string;
    cancelText?: string;
    confirmVariant?: "primary" | "danger";
    size?: ModalSize;
  }) => Promise<boolean>;
  info: (
    contentOrOptions: React.ReactNode | ModalInfoOptions,
    title?: string,
    options?: ModalOptions
  ) => Promise<void>;
  success: (
    contentOrOptions: React.ReactNode | ModalInfoOptions,
    title?: string,
    options?: ModalOptions
  ) => Promise<void>;
  warning: (
    contentOrOptions: React.ReactNode | ModalInfoOptions,
    title?: string,
    options?: ModalOptions
  ) => Promise<void>;
  error: (
    contentOrOptions: React.ReactNode | ModalInfoOptions,
    title?: string,
    options?: ModalOptions
  ) => Promise<void>;
}

let modalContainer: HTMLElement | null = null;
let modalRoot: ReturnType<typeof createRoot> | null = null;
let modalCleanupTimer: NodeJS.Timeout | null = null;

const getModalContainer = () => {
  if (!modalContainer) {
    modalContainer = document.createElement("div");
    modalContainer.id = "adnaan-modal-root";
    document.body.appendChild(modalContainer);
    modalRoot = createRoot(modalContainer);
  }

  // 清除之前的清理定时器
  if (modalCleanupTimer) {
    clearTimeout(modalCleanupTimer);
    modalCleanupTimer = null;
  }

  return { container: modalContainer, root: modalRoot };
};

// 清理Modal容器（延迟执行，避免频繁创建销毁）
const scheduleModalCleanup = () => {
  if (modalCleanupTimer) {
    clearTimeout(modalCleanupTimer);
  }

  modalCleanupTimer = setTimeout(() => {
    if (modalContainer && modalRoot) {
      try {
        modalRoot.unmount();
      } catch (e) {
        console.error("Error unmounting modal root:", e);
      }

      try {
        if (modalContainer.parentNode) {
          modalContainer.parentNode.removeChild(modalContainer);
        }
      } catch (e) {
        console.error("Error removing modal container:", e);
      }

      modalContainer = null;
      modalRoot = null;
    }
    modalCleanupTimer = null;
  }, 1000);
};

const showModal = (
  content: React.ReactNode,
  options: ModalOptions = {}
): Promise<void> => {
  return new Promise((resolve) => {
    const { root } = getModalContainer();
    if (!root) {
      console.error("Failed to create modal root");
      resolve();
      return;
    }

    const handleClose = () => {
      root.render(
        React.createElement(ModalComponent, {
          isOpen: false,
          onClose: () => {},
          children: content,
          ...options,
        })
      );

      setTimeout(() => {
        scheduleModalCleanup();
        resolve();
      }, duration.normal);
    };

    root.render(
      React.createElement(ModalComponent, {
        isOpen: true,
        onClose: handleClose,
        children: content,
        ...options,
      })
    );
  });
};

const showConfirm = (options: {
  title?: string;
  message: React.ReactNode;
  confirmText?: string;
  cancelText?: string;
  confirmVariant?: "primary" | "danger";
  size?: ModalSize;
}): Promise<boolean> => {
  return new Promise((resolve) => {
    const { root } = getModalContainer();
    if (!root) {
      console.error("Failed to create modal root");
      resolve(false);
      return;
    }

    const handleClose = (result: boolean) => {
      root.render(
        React.createElement(ModalComponent, {
          isOpen: false,
          onClose: () => {},
          children: null,
        })
      );

      setTimeout(() => {
        scheduleModalCleanup();
        resolve(result);
      }, duration.normal);
    };

    const footer = React.createElement(
      "div",
      { style: { display: "flex", gap: spacing["3"], width: "100%" } },
      React.createElement(Button, {
        onClick: () => handleClose(false),
        children: options.cancelText || "取消",
      }),
      React.createElement(Button, {
        $variant: options.confirmVariant || "primary",
        onClick: () => handleClose(true),
        children: options.confirmText || "确定",
      })
    );

    root.render(
      React.createElement(ModalComponent, {
        isOpen: true,
        onClose: () => handleClose(false),
        title: options.title || "确认",
        size: options.size,
        footer,
        children: React.createElement(
          "p",
          {
            style: {
              margin: `${spacing["4"]} 0`,
              color: "var(--text-primary)",
              lineHeight: "1.6",
            },
          },
          options.message
        ),
      })
    );
  });
};

const showInfoModal = (
  contentOrOptions: React.ReactNode | ModalInfoOptions,
  title?: string,
  options?: ModalOptions
): Promise<void> => {
  // 如果第一个参数是对象，则使用对象参数形式
  if (
    typeof contentOrOptions === "object" &&
    contentOrOptions !== null &&
    !React.isValidElement(contentOrOptions) &&
    "title" in contentOrOptions
  ) {
    const opts = contentOrOptions as ModalInfoOptions;
    const content = opts.content || opts.message || "";
    const modalTitle = opts.title || title || "信息";
    const modalSize = opts.size || (opts.width ? undefined : "medium");
    const modalOptions: ModalOptions = {
      ...options,
      title: modalTitle,
      size: modalSize,
      width: opts.width,
      closeOnOverlayClick:
        opts.closeOnOverlayClick ?? options?.closeOnOverlayClick,
      closeOnEsc: opts.closeOnEsc ?? options?.closeOnEsc,
      showCloseButton: opts.showCloseButton ?? options?.showCloseButton,
      centerContent: opts.centerContent ?? options?.centerContent,
      className: opts.className ?? options?.className,
    };

    return showModal(content, modalOptions);
  }

  // 否则使用传统参数形式
  return showModal(contentOrOptions as React.ReactNode, {
    ...options,
    title: title || "信息",
  });
};

const modal: ModalAPI = {
  show: showModal,
  confirm: showConfirm,
  info: showInfoModal,
  success: (contentOrOptions, title, options) => {
    if (
      typeof contentOrOptions === "object" &&
      contentOrOptions !== null &&
      !React.isValidElement(contentOrOptions) &&
      "title" in contentOrOptions
    ) {
      const opts = contentOrOptions as ModalInfoOptions;
      return showInfoModal(
        { ...opts, title: opts.title || title || "成功" },
        undefined,
        options
      );
    }
    return showModal(contentOrOptions as React.ReactNode, {
      ...options,
      title: title || "成功",
    });
  },
  warning: (contentOrOptions, title, options) => {
    if (
      typeof contentOrOptions === "object" &&
      contentOrOptions !== null &&
      !React.isValidElement(contentOrOptions) &&
      "title" in contentOrOptions
    ) {
      const opts = contentOrOptions as ModalInfoOptions;
      return showInfoModal(
        { ...opts, title: opts.title || title || "警告" },
        undefined,
        options
      );
    }
    return showModal(contentOrOptions as React.ReactNode, {
      ...options,
      title: title || "警告",
    });
  },
  error: (contentOrOptions, title, options) => {
    if (
      typeof contentOrOptions === "object" &&
      contentOrOptions !== null &&
      !React.isValidElement(contentOrOptions) &&
      "title" in contentOrOptions
    ) {
      const opts = contentOrOptions as ModalInfoOptions;
      return showInfoModal(
        { ...opts, title: opts.title || title || "错误" },
        undefined,
        options
      );
    }
    return showModal(contentOrOptions as React.ReactNode, {
      ...options,
      title: title || "错误",
    });
  },
};

export default modal;
export { ModalComponent as Modal };
